package tt.dz.egobus.servicemanager.service.impl;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tt.dz.egobus.base.dao.BaseDao;
import tt.dz.egobus.servicemanager.base.service.AbstractExtendService;
import tt.dz.egobus.servicemanager.bean.SpringConfigConstant;
import tt.dz.egobus.servicemanager.core.exception.BusinessException;
import tt.dz.egobus.servicemanager.dao.BusDao;
import tt.dz.egobus.servicemanager.entities.Bus;
import tt.dz.egobus.servicemanager.service.BusRegisterServiceService;
import tt.dz.egobus.servicemanager.service.BusService;
import tt.dz.egobus.servicemanager.service.BusinessExceptionAlertService;
import tt.dz.egobus.servicemanager.service.DriverRegisterBusRelativeService;
import tt.dz.egobus.servicemanager.util.QRCodeUtils;
import tt.dz.egobus.servicemanager.vo.BusQRCodeVo;

import java.io.File;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static tt.dz.egobus.servicemanager.bean.ServiceManagerCodeStatus.PARAM_ENTITY_ERROR;
import static tt.dz.egobus.servicemanager.bean.ServiceManagerCodeStatus.PARAM_ILLEGAL_ERROR;

/**
 * @author Anson
 * @date 17-3-16
 * @name 车辆服务层
 * @since 1.0.1
 */
@Service("busServiceImpl")
public class BusServiceImpl extends AbstractExtendService<Bus, String> implements BusService {

    @Autowired
    @Qualifier("busDaoImpl")
    private BusDao dao;

    @Autowired
    @Qualifier("businessExceptionAlertServiceImpl")
    private BusinessExceptionAlertService exceptionAlertService;


    @Autowired
    @Qualifier("busRegisterServiceServiceImpl")
    private BusRegisterServiceService registerService;

    @Autowired
    @Qualifier("driverRegisterBusRelativeServiceImpl")
    private DriverRegisterBusRelativeService driverRegisterBusRelativeService;


    @Autowired
    @Qualifier("springConfigConstant")
    private SpringConfigConstant config;

    @Override
    protected BaseDao<Bus, String> getSelfDao() {
        return this.dao;
    }

    @Override
    public byte[] generationQRCode(String id) throws BusinessException {
        Bus bus = this.get(id);
        if (bus == null) {
            throw new BusinessException(PARAM_ILLEGAL_ERROR.getCodeStatus());
        }

        BusQRCodeVo vo = new BusQRCodeVo();
        vo.setBusId(id);
        String json = JSONObject.toJSONString(vo);
        byte[] bytes = null;
        String logoFilePath = config.getEgobusLogoPath();
        boolean isExitLogoFile = false;
        //判断是否存在有效的二维码
        if (!StringUtils.isBlank(logoFilePath)) {
            URL url = BusServiceImpl.class.getResource("/" + logoFilePath);
            if (url != null) {
                logoFilePath = url.getFile();
                isExitLogoFile = new File(logoFilePath).exists();
            }
        }

        if (!isExitLogoFile) {
            bytes = QRCodeUtils.createQRCode(json);
        } else {
            bytes = QRCodeUtils.createLogoQRCode(json, logoFilePath);
        }
        return bytes;
    }

    @Override
    @Transactional
    public boolean updateBusUseStatus(String busId) {
        return this.updateBusStatus(busId, Bus.BusTypeEnum.USE);
    }

    @Override
    @Transactional
    public boolean updateBusStatus(String busId, Bus.BusTypeEnum type) throws BusinessException {
        if (StringUtils.isEmpty(busId) || type == null) {
            throw new BusinessException(PARAM_ILLEGAL_ERROR.getCodeStatus());
        }

        Bus bus = this.get(busId);
        if (bus == null) {
            throw new BusinessException(PARAM_ENTITY_ERROR.getCodeStatus());
        }
        bus.setStatus(type.getStatus());
        try {
            this.dao.update(bus);
            return true;
        } catch (Exception e) {
            return false;
        }

    }

    @Override
    @Transactional
    public boolean updateBusUnUseStatus(String busId) {
        return this.updateBusStatus(busId, Bus.BusTypeEnum.NOT_USE);
    }

    @Override
    public boolean updateBusExceptionStatus(String busId) {
        return this.updateBusStatus(busId, Bus.BusTypeEnum.EXCEPTION);
    }

    @Override
    @Transactional
    public Bus getUnBrokenBusByBusNo(String busNo) {
        if (StringUtils.isBlank(busNo)) {
            return null;
        }
        Map<String, Object> params = new HashMap<String, Object>(2);
        params.put("eq#carNo", busNo);
        params.put("ne#status", Bus.BusTypeEnum.BROKEN.getStatus());
        List<Bus> ls = this.dao.list(params);
        if (CollectionUtils.isEmpty(ls)) {
            return null;
        }
        return ls.get(0);
    }

    @Override
    @Transactional
    public void updateExceptionBusUnUsed(String busNo) {
        Bus bus = this.getUnBrokenBusByBusNo(busNo);
        if (bus == null) {
            //未找到未报废的车辆信息
            return;
        }
        //确信当前车辆状态处于异常或者维修中的时候
        // 修改其状态为未使用
        if (bus.assertException() || bus.assertRepair()) {
            bus.setNotUse();
            this.dao.update(bus);
        }
    }


    @Override
    @Transactional
    public void preDeleteBusService(String id) throws BusinessException {
        //判断是否存在有效的服务绑定关系
        this.registerService.validateServiceRelative(id, true);
        //判断是否存在有效的司机之间绑定关系
        this.driverRegisterBusRelativeService.validateDriverelative(id, true);
        //删除车辆的服务注册
        this.registerService.deleteRelativeByBusId(id);
        //删除司机之间绑定关系
        this.driverRegisterBusRelativeService.deleteDriverRelativeByBusId(id);
    }

    /**
     * @param bus 车辆信息
     * @author Anson
     * @date 17-5-24
     * @name 判断当前状态是否处于司机控制的状态种
     * 原来车辆状态处于"使用中"的状态
     * 以及
     * 原来并没有处于"使用中",但是当前修改了状态使其在"使用中"的状态
     * 说明是处于司机控制中
     * @since 1.0.4
     */
    @Override
    @Transactional
    public boolean isBusStatusInDriverController(Bus bus) {
        if (bus == null) {
            throw new BusinessException(PARAM_ENTITY_ERROR.getCodeStatus());
        }
        String busId = bus.getId();
        if (StringUtils.isBlank(busId)) {
            throw new BusinessException(PARAM_ILLEGAL_ERROR.getCodeStatus());
        }
        int status = bus.getStatus();
        if (Bus.BusTypeEnum.getBusType(status) == null) {
            throw new BusinessException(PARAM_ILLEGAL_ERROR.getCodeStatus());
        }
        Map<String, Object> params = new HashMap<String, Object>(2);
        params.put("eq#id", busId);
        params.put("eq#status", Bus.BusTypeEnum.USE.getStatus());
        int count = this.dao.count(params);
        boolean isDriverController = false;
        if (count > 0) {
            //说明原来车辆状态处于"使用中"的状态
            //说明处于司机控制阶段
            isDriverController = true;
        }

        if (bus.assertUsed() && count == 0) {
            // 原来并没有处于"使用中",但是当前修改了状态使其在"使用中"的状态
            // 此时使不能修改的,这里司机控制状态
            isDriverController = true;
        }

        return isDriverController;
    }
}
